/**
 * projectName: springboot-mybatis
 * fileName: JwtInterceptor.java
 * packageName: com.zb.api.business.interceptor
 * date: 2022-02-21 13:37
 * copyright(c) 2017-2020 xxx公司
 */
package com.zb.api.business.interceptor;
/**
 * @version: V1.0
 * @author: fendo
 * @className: JwtInterceptor
 * @packageName: com.zb.api.business.interceptor
 * @description: 拦截器
 * @data: 2022-02-21 13:37
 **/

import com.alibaba.fastjson.JSONObject;
import com.zb.api.business.entity.UserEntity;
import com.zb.api.business.service.UserService;
import com.zb.api.common.conts.Const;
import com.zb.api.utils.JwtUtils;
import com.zb.api.utils.UserThreadLocal;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @description:
 * @author: User
 * @date: 2022-02-21 13:37
 */
@Slf4j
public class JwtInterceptor implements HandlerInterceptor {
    @Autowired
    JwtUtils jwtUtils;
    @Autowired
    UserService userService;
    @Autowired
    StringRedisTemplate redisTemplate;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("jwt 校验 拦截器");
        log.info(request.getRequestURL().toString());
        // header 变量值在配置文件中配置
        String token = request.getHeader(jwtUtils.getHeader());
        if (StringUtils.isEmpty(token)) {
            throw new JwtException("未登录！");
        }
        Claims claim = jwtUtils.getClaimByToken(token);
        if (claim == null) {
            throw new JwtException("token异常！");
        }
        if (jwtUtils.isTokenExpired(claim)) {
            throw new JwtException("token已过期");
        }
        String username = claim.getSubject();
        log.info("用户-{}，正在登陆！", username);
        if(StringUtils.isEmpty(username)){
            throw new JwtException("用户信息异常");
        }
        // 从缓存中获取
        UserEntity userEntity = new UserEntity();
        String s = redisTemplate.opsForValue().get(Const.USER_INFO_KEY + token);
        if(StringUtils.isNotEmpty(s)){
            userEntity = JSONObject.parseObject(s, UserEntity.class);
        }else{
            userEntity = userService.getUserByUserName(username);
        }
        UserThreadLocal.set(userEntity);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        //关闭threadLocal
        UserThreadLocal.remove();
    }
}